#include "stdafx.h"

namespace
{
	class singleton
	{
	public:
		static hc::TDebugStream& Instance()
		{
			static hc::TDebugStream _DebugStream;
			return _DebugStream;
		}
	private:
		singleton() {}
		singleton(const singleton &);             
		singleton & operator=(const singleton &); 
		//hc::TMutex m_mtx;
	};
}

namespace hc 
{
	TDebugStream::TDebugStream()
	{
		//RAW_TRACE
	}	

	TDebugStream::~TDebugStream()
	{
		//RAW_TRACE
	}

	TDebugStream& TDebugStream::WriteString( const string& iString )
	{
		TLock	_(m_mutex);
		for(list<PWriter>::iterator i = m_writers.begin(); i != m_writers.end();)
		{
			try
			{
				(*i)->WriteString( iString );
				++i;
			}
			catch( std::exception& ex )
			{
				i = m_writers.erase( i );
				cerr << "Error in TDebugStream::WriteString:" << ex.what() << "\n";
			}
		}
		return *this;
	}

	void TDebugStream::AddWriter( PWriter iWriter )
	{
		//RAW_TRACE
		TLock _(m_mutex);
		m_writers.push_back(iWriter);
	}

	void TDebugStream::RemoveWriter( PWriter iWriter )
	{
		//RAW_TRACE
		TLock _(m_mutex);
		m_writers.remove(iWriter);
	}
	bool TDebugStream::GetEnabled() const
	{ 
		return !m_writers.empty(); 
	}
//----------------------------------------------------------------------------
	string now()
	{
		boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
		boost::gregorian::date _date = now.date();
		boost::posix_time::time_duration _time = now.time_of_day();
		stringstream ss;
		ss << _date << ".";
		ss << _time.hours() << "-";
		ss << _time.minutes() << "-";
		ss << _time.seconds();
		return ss.str();
	}

//----------------------------------------------------------------------------
	TPermanentFileWriter::TPermanentFileWriter( const char* iName )
	{
		m_log.open(iName, std::ios::app);
		if (!m_log.is_open())
			throw ERuntimeException(errno,ex_val("File",string(iName)));
	}

	TPermanentFileWriter::~TPermanentFileWriter()
	{
		m_log.close();
	}

	void TPermanentFileWriter::WriteString( const string& iString )
	{
		m_log << now() << " " << iString << std::endl;
	}
//-----------------------------------------------------------------------------
	void TDebugConsoleWriter::WriteString( const string& iString )
	{
		cout << now() << " " << iString;
	}
//-----------------------------------------------------------------------------
	TDebugStream& Trace()
	{
		return singleton::Instance();
	}
};